package org.polaris.authority.service.impl;

import org.polaris.authority.annotation.PolarisPermission;
import org.polaris.authority.domain.Permission;
import org.polaris.authority.mapper.PermissionMapper;
import org.polaris.authority.query.PermissionQuery;
import org.polaris.authority.service.IPermissionScanService;
import org.polaris.basic.enums.RequestTypeEnum;
import org.polaris.basic.service.impl.BaseServiceImpl;
import org.polaris.basic.tool.ClassUtils;
import org.polaris.basic.tool.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Objects;

@Service
@Primary
public class PermissionScanServiceImpl extends BaseServiceImpl<Permission> implements IPermissionScanService {

    @Autowired
    private PermissionMapper permissionMapper;

    //加载配置文件
    @Value("${polaris.permission.scan-base-package}")
    private String scanBasePackage;

    //扫描所有controller
    @Transactional
    @Override
    public void scan() {
        //删除所有权限
        permissionMapper.deleteAll();
        //获取所有controller类
        List<Class> allClassName = ClassUtils.getAllClassName(this.scanBasePackage);
        //判断类上是否有自定义注解
        for (Class c : allClassName){
            PolarisPermission polarisPermission = (PolarisPermission)c.getAnnotation(PolarisPermission.class);
            //如果没有自定义注解跳出当次循环
            if (Objects.isNull(polarisPermission)){
                continue;
            }
            //获取类路径
            RequestMapping requestMapping = (RequestMapping)c.getAnnotation(RequestMapping.class);
            //RequestMapping的value是数组 value是RequestMapping的一个属性
            String classUrl = requestMapping.value()[0];

            //将类封装成一个permission对象
            Permission classPermission = new Permission();
            classPermission.setName(polarisPermission.name());
            classPermission.setDescs(polarisPermission.descs());
            //getSimpleName是类名 getName是全限定路径
            classPermission.setSn(c.getSimpleName());
            classPermission.setUrl(classUrl);
            //保存父权限拿到id
            permissionMapper.add(classPermission);
            //拿到当前类所有方法
            Method[] methods = c.getMethods();
            //循环判断方法上是否有自定义注解
            for (Method method : methods){
                PolarisPermission methodAnnotation = method.getAnnotation(PolarisPermission.class);
                //没有直接跳出本次循环
                if (Objects.isNull(methodAnnotation)){
                    continue;
                }
                //如果有就封装对象
                Permission methodPermission = new Permission();
                methodPermission.setName(methodAnnotation.name());
                methodPermission.setDescs(methodAnnotation.descs());
                methodPermission.setSn(c.getSimpleName()+":"+method.getName());
                String methodUrl = getMethodUrl(method);
                methodPermission.setUrl(classUrl+methodUrl);
                methodPermission.setParentId(classPermission.getId());
                permissionMapper.add(methodPermission);
            }
        }

    }

    @Override
    public List<Permission> getPermissionTree() {
        return permissionMapper.getPermissionTree();
    }

    //获取方法路径
    private String getMethodUrl(Method method){
        String methodUrl = "";
        // 取枚举中定义的所有的请求类型
        RequestTypeEnum[] requestTypeEnums = RequestTypeEnum.values();
        for (RequestTypeEnum typeEnum : requestTypeEnums) {
            // 根据枚举中的不同的请求类型的class获取该类型对应的注解对象
            Annotation annotation = method.getAnnotation(typeEnum.getRequestType());
            // 如果该请求类型注解不存在就跳过
            if(Objects.isNull(annotation)){
                continue;
            }
            try {
                // 如果该请求类型注解存在,就获取它里面的value方法
                Method annotationMethod = annotation.annotationType().getMethod("value");
                // 通过invoke调用该对象的value方法,获取结果
                String[] value = (String[]) annotationMethod.invoke(annotation);
                // 如果value不为空且长度大于0,就赋值给methodUrl,并跳出循环
                if(value != null && value.length > 0){
                    methodUrl = value[0];
                    break;
                }
            }catch (Exception e) {
                e.printStackTrace();
                continue;
            }
        }
        return methodUrl;
        /*PutMapping putMapping = method.getAnnotation(PutMapping.class);
        if(Objects.nonNull(putMapping)){
            methodUrl = putMapping.value() != null && putMapping.value().length > 0 ? putMapping.value()[0] : "";
        }
        PostMapping postMapping = method.getAnnotation(PostMapping.class);
        if(Objects.nonNull(postMapping)){
            methodUrl = postMapping.value() != null && postMapping.value().length > 0 ? postMapping.value()[0] : "";
        }
        GetMapping getMapping = method.getAnnotation(GetMapping.class);
        if(Objects.nonNull(getMapping)){
            methodUrl = getMapping.value() != null && getMapping.value().length > 0? getMapping.value()[0] : "";
        }
        DeleteMapping deleteMapping = method.getAnnotation(DeleteMapping.class);
        if(Objects.nonNull(deleteMapping)){
            methodUrl = deleteMapping.value() != null && deleteMapping.value().length > 0 ? deleteMapping.value()[0] : "";
        }
        PatchMapping patchMapping = method.getAnnotation(PatchMapping.class);
        if(Objects.nonNull(patchMapping)){
            methodUrl = patchMapping.value() != null && patchMapping.value().length > 0 ? patchMapping.value()[0] : "";
        }*/
        //return methodUrl;
    }
}
